//<reference  path="../typings/requirejs/require.d.ts"/>
//<reference  path="../typings/jquery/jquery.d.ts"/>

module Trust.Api {
    //export interface IEntitySet<T> {
    //    // ...
    //    map<U>(callbackfn: (value: T, index: number, array: T[]) => U): U[];
    //    // ...
    //}
    export interface HttpRequest<T> {
        success? (callback: (data: T) => void): HttpRequest<T>;
        error? (callback: (error: Error) => void): HttpRequest<T>;
        always? (callback: () => void): HttpRequest<T>;
    }

    export interface QueryParameter {
        $top?: number;
        $skip?: number;
        $inlinecount: boolean;
        $filter?: string;
        $orderby?: string;
        $select?: string;
        $expand?: boolean;
    }

    class JQueryHttpRequest<T> implements HttpRequest<T> {
        private onSuccess: Function;
        private onError: Function;
        private onAlways: Function;

        constructor(jqueryRun, createData: (data) => T) {
            var that = this;
            var onSuccessFn = function (data) {
                if (that.onSuccess) {
                    that.onSuccess(createData(data));
                }
            };
            var onErrorFn = function (data) {
                if (that.onError) {
                    that.onError(data);
                }
            };
            var onAlwaysFn = function () {
                if (that.onAlways) {
                    that.onAlways();
                }
            };
            jqueryRun.done(onSuccessFn).fail(onErrorFn).always(onAlwaysFn);
        }

        success = function (fn) {
            this.onSuccess = fn;
            return this;
        }

        error = function (fn) {
            this.onError = fn;
            return this;
        }

        always = function (fn) {
            this.onAlways = fn;
            return this;
        }
    }

    export interface IRepository<T> {
        getItems(query?: QueryParameter): HttpRequest<collections.Set<T>>;
        postItem(data: T): HttpRequest<T>;
        putItem(data: T): HttpRequest<T>;
        deleteItem(data: T): HttpRequest<T>;
    }

    export class Repository<T> implements IRepository<T> {
        public apiUrl: string;
        private jquery: any;
        constructor(public entityName: string) {
            this.apiUrl = CONSTANST.appUrl + CONSTANST.currentLanguage + '/Api/' + entityName;
            var that = this;
            require(["jquery", "collections"], function ($, col) {
                that.jquery = $;
            });
        }

        getItems = function (query?: QueryParameter): HttpRequest<collections.Set<T>> {

            return new JQueryHttpRequest<collections.Set<T>>(this.jquery.ajax({
                type: "GET",
                url: this.apiUrl,
                data: query,
            }), function (data) { return data; });;
        };

        postItem = function (data: T): HttpRequest<T> {

            this.jquery.ajax({
                type: "POST",
                url: this.apiUrl,
                data: data
            });
            return null;
        };

        putItem = function (data: T): HttpRequest<T> {
            this.jquery.ajax({
                type: "PUT",
                url: this.apiUrl,
                data: data
            });
            return null;
        };

        deleteItem = function (data: T): HttpRequest<T> {
            this.jquery.ajax({
                type: "DELETE",
                url: this.apiUrl,
                data: data
            });
            return null;
        };
    }
}

class UserRepository extends Trust.Api.Repository<Trust.Casas.Model.User>
{
    constructor() {
        super("User");
    }
}

class RegionRepository extends Trust.Api.Repository<Trust.Casas.Model.Region>
{
    constructor() {
        super("Region");
    }
}

class UserDetailsRepository extends Trust.Api.Repository<Trust.Casas.Model.UserDetail>
{
    constructor() {
        super("UserDetail");
    }
}